package br.com.locasis.funcionalidades;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.servlet.ServletContext;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.international.StatusMessages;

import br.com.locasis.entity.Aluguel;
import br.com.locasis.entity.AluguelProduto;
import br.com.locasis.entity.Automovel;
import br.com.locasis.entity.Cliente;
import br.com.locasis.entity.Cobertura;
import br.com.locasis.entity.FormaPagamento;
import br.com.locasis.entity.HistoricoAluguel;
import br.com.locasis.entity.Pais;
import br.com.locasis.entity.Produto;
import br.com.locasis.entity.TabelaValorAutomovel;
import br.com.locasis.entity.TipoValorPagamento;
import br.com.locasis.entity.Usuario;
import br.com.locasis.entity.ValorPagamento;
import br.com.locasis.utilitarios.DataUtil;
import br.com.locasis.utilitarios.NumeroPorExtenso;
import br.com.locasis.utilitarios.UtilDate;
import br.com.locasis.utilitarios.UtilUfs;

@Name("cadastrarAluguel")
@Scope(ScopeType.CONVERSATION)
//@Restrict(value="#{identity.hasRole('"+PerfilUsuario.PERFIL_PETSHOP+"')}")
public class CadastrarAluguel {
	
	@In(create=true)
	private EntityManager entityManager;
	
	@In(create=true)
	private DominioController dominioController;
	
	@In(required = false)
    Usuario usuarioLogado;
	
	@In(value = "statusMessages")
	protected StatusMessages messages;

	private Aluguel aluguelEdicao;
	
	private Cobertura coberturaEdicao;
	
	private Aluguel aluguelSelecionado;
	
	private Aluguel aluguelSalvo;
	
	private HistoricoAluguel historicoEdicao;
	
	private List<Aluguel> listaAlugueis;
	
	private List<Aluguel> listaAlugueisFinalizados;
	
	private List<HistoricoAluguel> listaHistoricosAluguel;
	
	private List<Automovel> listaAutomoveis;
	
	private List<Cliente> listaClientes;
	
	private List<SelectItem> listaFormasPagamento;
	
	private List<SelectItem> listaUsuariosAutorizacao;
	
	private List<SelectItem> listaTabelasValor;
	
	private List<SelectItem> listaUfs;
	
	private List<AluguelProduto> listaProdutos;
	
	private Date dataAluguel;
	
	private Automovel automovelPesquisa;
	
	private Automovel automovelSelecionado;
	
	private Cliente clientePesquisa;
	
	private Cliente clienteSelecionado;
	
	private Integer idFormaPagamento;
	
	private Integer idTabelaSelecionada;
	
	private Integer idPaisCondutor;
	
	private String selectedTab;
	
	private ValorPagamento valorKmExtra;
	
	private ValorPagamento valorHoraExtra;
	
	private ValorPagamento valorDiarias;
	
	private ValorPagamento valorTaxaServico;
	
	private ValorPagamento valorTotal;
	
	private ValorPagamento valorCombustivel;
	
	private ValorPagamento valorTaxaLimpeza;

	private ValorPagamento valorProdutos;
	
	private boolean selecionadoTodos;
	
	private boolean finalizacao;
	
	private AluguelProduto produtoEdicao;
	
	private Integer idProdutoSelecionado;
	
	private Integer idUsuarioSelecionado;
	
	private List<SelectItem> produtos;
	
	private boolean edicaoProduto;
	
	private ValorPagamento valorDesconto;
	
	private boolean exibeModalDesconto;
	
	private boolean exibeModalRespostaDesconto;
	
	private boolean exibeModalConfirmacaoDesconto;
	
	private String filterValue;
	
	private String filterValueFin;
	
	public String getFilterValueFin() {
		return filterValueFin;
	}

	public void setFilterValueFin(String filterValueFin) {
		this.filterValueFin = filterValueFin;
	}

	public String getFilterValue() {
		return filterValue;
	}

	public void setFilterValue(String filterValue) {
		this.filterValue = filterValue;
	}

	public boolean isExibeModalConfirmacaoDesconto() {
		return exibeModalConfirmacaoDesconto;
	}

	public void setExibeModalConfirmacaoDesconto(
			boolean exibeModalConfirmacaoDesconto) {
		this.exibeModalConfirmacaoDesconto = exibeModalConfirmacaoDesconto;
	}

	public boolean isExibeModalDesconto() {
		return exibeModalDesconto;
	}

	public void setExibeModalDesconto(boolean exibeModalDesconto) {
		this.exibeModalDesconto = exibeModalDesconto;
	}

	public boolean isExibeModalRespostaDesconto() {
		return exibeModalRespostaDesconto;
	}

	public void setExibeModalRespostaDesconto(boolean exibeModalRespostaDesconto) {
		this.exibeModalRespostaDesconto = exibeModalRespostaDesconto;
	}

	public ValorPagamento getValorDesconto() {
		return valorDesconto;
	}

	public void setValorDesconto(ValorPagamento valorDesconto) {
		this.valorDesconto = valorDesconto;
	}

	public ValorPagamento getValorProdutos() {
		if (valorProdutos == null) {
			valorProdutos = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.PRODUTOS));
		}
		return valorProdutos;
	}

	public void setValorProdutos(ValorPagamento valorProdutos) {
		this.valorProdutos = valorProdutos;
	}

	public boolean isEdicaoProduto() {
		return edicaoProduto;
	}

	public void setEdicaoProduto(boolean edicaoProduto) {
		this.edicaoProduto = edicaoProduto;
	}

	public List<SelectItem> getProdutos() {
		if (produtos == null) {
			produtos = new ArrayList<SelectItem>();
			produtos.add(new SelectItem(null,"Selecione"));
			List<Produto> lista = entityManager.createQuery("select p from Produto p where p.flgAtivo is true").getResultList();
			for(Produto p : lista){
				produtos.add(new SelectItem(p.getIdProduto(),p.getNome()));
			}
		}
		return produtos;
	}

	public void setProdutos(List<SelectItem> produtos) {
		this.produtos = produtos;
	}

	public Integer getIdProdutoSelecionado() {
		return idProdutoSelecionado;
	}

	public void setIdProdutoSelecionado(Integer idProdutoSelecionado) {
		this.idProdutoSelecionado = idProdutoSelecionado;
	}

	public Integer getIdUsuarioSelecionado() {
		return idUsuarioSelecionado;
	}

	public void setIdUsuarioSelecionado(Integer idUsuarioSelecionado) {
		this.idUsuarioSelecionado = idUsuarioSelecionado;
	}

	public AluguelProduto getProdutoEdicao() {
		if (produtoEdicao == null) {
			produtoEdicao = new AluguelProduto();
			produtoEdicao.setProduto(new Produto());
		}
		return produtoEdicao;
	}

	public void setProdutoEdicao(AluguelProduto produtoEdicao) {
		this.produtoEdicao = produtoEdicao;
	}

	public List<AluguelProduto> getListaProdutos() {
		if (listaProdutos == null) {
			listaProdutos = new ArrayList<AluguelProduto>();
		}
		return listaProdutos;
	}

	public void setListaProdutos(List<AluguelProduto> listaProdutos) {
		this.listaProdutos = listaProdutos;
	}

	public boolean isFinalizacao() {
		return finalizacao;
	}

	public void setFinalizacao(boolean finalizacao) {
		this.finalizacao = finalizacao;
	}

	public boolean isSelecionadoTodos() {
		return selecionadoTodos;
	}

	public void setSelecionadoTodos(boolean selecionadoTodos) {
		this.selecionadoTodos = selecionadoTodos;
	}

	public ValorPagamento getValorKmExtra() {
		if (valorKmExtra == null) {
			valorKmExtra = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.KM_EXTRA));
		}
		return valorKmExtra;
	}

	public void setValorKmExtra(ValorPagamento valorKmExtra) {
		this.valorKmExtra = valorKmExtra;
	}

	public ValorPagamento getValorHoraExtra() {
		if (valorHoraExtra == null) {
			valorHoraExtra = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.HORA_EXTRA));
		}
		return valorHoraExtra;
	}

	public void setValorHoraExtra(ValorPagamento valorHoraExtra) {
		this.valorHoraExtra = valorHoraExtra;
	}

	public ValorPagamento getValorDiarias() {
		if (valorDiarias == null) {
			valorDiarias = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.DIARIAS));
		}
		return valorDiarias;
	}
	
	public void atualizaProdutoListener(ValueChangeEvent evento){
		if(evento.getNewValue() != null){
			getProdutoEdicao().setProduto(entityManager.find(Produto.class, (Integer)evento.getNewValue()));
		}
	}
	
	public void selecionaTabelaListener(ValueChangeEvent evento){
		if(evento != null && evento.getNewValue() != null){
			idTabelaSelecionada = (Integer)evento.getNewValue();
		}
	}
	
	public void selecionarValorPagamento(ValorPagamento valor){
		valorDesconto = valor;
	}
	
	public byte[] recuperaFoto(String url){
		try {
			InputStream is = null;    
			byte[] buffer = null;   
			is = new FileInputStream(url);   
			buffer = new byte[is.available()];   
			is.read(buffer);   
			is.close(); 
			return buffer;
		} catch (FileNotFoundException e) {
			System.out.println("File Not Found.");
			e.printStackTrace();
		}catch (IOException e1){
			System.out.println("Error Reading The File.");
			e1.printStackTrace();
		}
		return null;
	}
	
	public void lancarDesconto(){
		if(usuarioLogado == null){
			getValorDesconto().setDesconto(0F);
			messages.add(Severity.ERROR,"O usuário administrador não pode lançar descontos.");
			return;
		}else if(usuarioLogado.getPerfil().getVlrMaxDesconto() == null ||
				usuarioLogado.getPerfil().getVlrMaxDesconto().equals(0F)){
			getValorDesconto().setDesconto(0F);
			messages.add(Severity.ERROR,"O seu perfil não tem permissão para lançar desconto.");
			return;
		}
		if(getValorDesconto().getTipoDesconto() != null){
			if(getValorDesconto().getTipoDesconto().equals(1)){
				if(getValorDesconto().getDesconto() > usuarioLogado.getPerfil().getVlrMaxDesconto()){
					getValorDesconto().setDesconto(0F);
					messages.add(Severity.ERROR,"Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
					return;
				}
				Float valor = 0F;
				if(getValorDesconto().getValorUnitario() != null)
					valor = getValorDesconto().getValorUnitario()*(1-(getValorDesconto().getDesconto()/100));
				if(getValorDesconto().getQuantidade() != null && valor >= 0)
					getValorDesconto().setTotal(valor*getValorDesconto().getQuantidade());
			}else{
				Float valor = 0F;
				if(getValorDesconto().getValorUnitario() != null && 
						getValorDesconto().getQuantidade() != null){
				Float percentual = (getValorDesconto().getDesconto() * 100)/(getValorDesconto().getValorUnitario()*getValorDesconto().getQuantidade());
					if(percentual > usuarioLogado.getPerfil().getVlrMaxDesconto()){
						getValorDesconto().setDesconto(0F);
						messages.add(Severity.ERROR,"Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
						return;
					}
					valor = (getValorDesconto().getValorUnitario()*getValorDesconto().getQuantidade())-getValorDesconto().getDesconto();
				}
				getValorDesconto().setTotal(valor);
			}
			atualizaTotalizadores();
			setValorDesconto(null);
		}
	}
	
	public void atualizaTotalProduto(){
		float valorParcial = 0F;
		if(getProdutoEdicao().getProduto().getIdProduto() != null &&
				getProdutoEdicao().getProduto().getValor() != null){
			if(getProdutoEdicao().getQuantidade() != null){
				valorParcial = getProdutoEdicao().getProduto().getValor() * getProdutoEdicao().getQuantidade();
				if(getProdutoEdicao().getDesconto() != null){
					if(getProdutoEdicao().getTipoDesconto() != null){
						if(getProdutoEdicao().getTipoDesconto().equals(1)){
							valorParcial = valorParcial * (1-(getProdutoEdicao().getDesconto()/100));
						}else{
							valorParcial = valorParcial - getProdutoEdicao().getDesconto();
						}
					}
				}
			}
		}
		getProdutoEdicao().setValorTotal(valorParcial);
	}
	
	public void inicializaPopupNovoProduto(){
		setProdutoEdicao(null);
		setIdProdutoSelecionado(null);
		setEdicaoProduto(false);
	}
	
	public void inicializaPopupEditarProduto(AluguelProduto aluguelProduto){
		setProdutoEdicao(aluguelProduto);
		setIdProdutoSelecionado(aluguelProduto.getProduto().getIdProduto());
		setEdicaoProduto(true);
	}
	
	public void salvarNovoProduto(){
		if(getProdutoEdicao().getQuantidade() == null){
			messages.add(Severity.ERROR,"O campo Quantidade é de preenchimento obrigatório");
			return;
		}
		Produto prod = entityManager.find(Produto.class, getIdProdutoSelecionado());
		getProdutoEdicao().setProduto(prod);
		if(getProdutoEdicao().getDesconto() == null){
			getProdutoEdicao().setDesconto(0F);
		}else{
			if(usuarioLogado.getPerfil().getVlrMaxDesconto() == null ||
					usuarioLogado.getPerfil().getVlrMaxDesconto().equals(0F)){
				getProdutoEdicao().setDesconto(0F);
				getProdutoEdicao().setValorTotal(prod.getValor() * getProdutoEdicao().getQuantidade());
				messages.add(Severity.ERROR,"O seu perfil não tem permissão para lançar desconto.");
			}else{
				if(getProdutoEdicao().getTipoDesconto().equals(1)){
					if(getProdutoEdicao().getDesconto() > usuarioLogado.getPerfil().getVlrMaxDesconto()){
						messages.add(Severity.ERROR,"Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
						getProdutoEdicao().setDesconto(0F);
						getProdutoEdicao().setValorTotal(prod.getValor() * getProdutoEdicao().getQuantidade());
					}
				}else{
					
					Float percentual = (getProdutoEdicao().getDesconto() * 100)/(prod.getValor()*getProdutoEdicao().getQuantidade());
					if(percentual > usuarioLogado.getPerfil().getVlrMaxDesconto()){
						getProdutoEdicao().setDesconto(0F);
						getProdutoEdicao().setValorTotal(prod.getValor() * getProdutoEdicao().getQuantidade());
						messages.add(Severity.ERROR,"Você não possui permissão para efetuar esse desconto, solicite à alguém autorizado.");
					}
				}
			}
		}
//		getProdutoEdicao().setProduto(entityManager.find(Produto.class, getIdProdutoSelecionado()));
		if(!isEdicaoProduto()){
			getListaProdutos().add(getProdutoEdicao());
		}
		atualizaTotalizadoresProduto();
	}
	
	public void atualizaTotalizadoresProduto(){
		Integer quantidade = 0;
		Float desconto = 0F;
		Float total = 0F;
		Float valorUnitario = 0F;
		for(AluguelProduto ap : getListaProdutos()){
			quantidade = quantidade + ap.getQuantidade();
			desconto = desconto + ap.getDesconto();
			valorUnitario = valorUnitario + ap.getProduto().getValor();
			total = total + ap.getValorTotal();
		}
		getValorProdutos().setQuantidade(quantidade);
		getValorProdutos().setDesconto(desconto);
		getValorProdutos().setValorUnitario(valorUnitario);
		getValorProdutos().setTotal(total);
		atualizaTotalizadores();
	}
	
	public void excluirProduto(AluguelProduto produto){
		getListaProdutos().remove(produto);
		if(produto.getIdAluguelProduto() != null){
			entityManager.remove(produto);
			entityManager.flush();
		}
		atualizaTotalizadoresProduto();
		messages.add(Severity.INFO,"Produto excluído com sucesso.");
	}
	
	public void atualizaValoresDiaria(){
		if(getIdTabelaSelecionada() != null){
			TabelaValorAutomovel tabelaAuto = entityManager.find(TabelaValorAutomovel.class, getIdTabelaSelecionada());
			if(getAluguelEdicao().getTotalDiarias() != null){
				getValorDiarias().setQuantidade(getAluguelEdicao().getTotalDiarias());
			}
			if(getAutomovelSelecionado() != null &&
					getAutomovelSelecionado().getValorDiaria() != null){
				getValorDiarias().setValorUnitario(tabelaAuto.getValorDiaria());
			}
			if(getAluguelEdicao().getTotalDiarias() != null && 
					tabelaAuto.getValorDiaria() != null){
				getValorDiarias().setTotal(getValorDiarias().getQuantidade() * tabelaAuto.getValorDiaria());
				atualizaTotalizadores();
			}
			getValorHoraExtra().setQuantidade(0);
			getValorHoraExtra().setValorUnitario(tabelaAuto.getValorHora());
			getValorHoraExtra().setTotal(0F);
	
			getValorKmExtra().setQuantidade(0);
			getValorKmExtra().setValorUnitario(tabelaAuto.getValorKm());
			getValorKmExtra().setTotal(0F);
			
			calculaDataPrevistaRetorno();
		}
	}

	public void setValorDiarias(ValorPagamento valorDiarias) {
		this.valorDiarias = valorDiarias;
	}

	public ValorPagamento getValorTaxaServico() {
		if (valorTaxaServico == null) {
			valorTaxaServico = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.TAXA_SERVICO));
		}
		return valorTaxaServico;
	}

	public void setValorTaxaServico(ValorPagamento valorTaxaServico) {
		this.valorTaxaServico = valorTaxaServico;
	}

	public ValorPagamento getValorTotal() {
		if (valorTotal == null) {
			valorTotal = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.TOTAL));
		}
		return valorTotal;
	}

	public void setValorTotal(ValorPagamento valorTotal) {
		this.valorTotal = valorTotal;
	}

	public ValorPagamento getValorCombustivel() {
		if (valorCombustivel == null) {
			valorCombustivel = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.COMBUSTIVEL));
		}
		return valorCombustivel;
	}

	public void setValorCombustivel(ValorPagamento valorCombustivel) {
		this.valorCombustivel = valorCombustivel;
	}

	public ValorPagamento getValorTaxaLimpeza() {
		if (valorTaxaLimpeza == null) {
			valorTaxaLimpeza = new ValorPagamento(
					dominioController.recuperaTipoValorPagamentoPorNome(
							TipoValorPagamento.TAXA_LIMPEZA));
		}
		return valorTaxaLimpeza;
	}

	public void setValorTaxaLimpeza(ValorPagamento valorTaxaLimpeza) {
		this.valorTaxaLimpeza = valorTaxaLimpeza;
	}

	public String getSelectedTab() {
		return selectedTab;
	}

	public void setSelectedTab(String selectedTab) {
		this.selectedTab = selectedTab;
	}

	public Integer getIdFormaPagamento() {
		return idFormaPagamento;
	}

	public void setIdFormaPagamento(Integer idFormaPagamento) {
		this.idFormaPagamento = idFormaPagamento;
	}

	public Integer getIdTabelaSelecionada() {
		return idTabelaSelecionada;
	}

	public void setIdTabelaSelecionada(Integer idTabelaSelecionada) {
		this.idTabelaSelecionada = idTabelaSelecionada;
	}

	public List<SelectItem> getListaFormasPagamento() {
		if (listaFormasPagamento == null) {
			listaFormasPagamento = new ArrayList<SelectItem>();
			listaFormasPagamento.add(new SelectItem(null,"Selecione"));
			List<FormaPagamento> lista = dominioController.getListaFormasPagamento();
			for(FormaPagamento f : lista){
				listaFormasPagamento.add(new SelectItem(f.getIdFormaPagamento(),f.getNome()));
			}
		}
		return listaFormasPagamento;
	}

	public void setListaFormasPagamento(List<SelectItem> listaFormasPagamento) {
		this.listaFormasPagamento = listaFormasPagamento;
	}

	public List<SelectItem> getListaUsuariosAutorizacao() {
		if (listaUsuariosAutorizacao == null) {
			listaUsuariosAutorizacao = new ArrayList<SelectItem>();
			listaUsuariosAutorizacao.add(new SelectItem(null,"Selecione"));
			if(usuarioLogado != null && 
					usuarioLogado.getPerfil().getPerfilAutorizacao() != null){
				List<Usuario> lista = entityManager.createQuery("select u from Usuario u where u.perfil.idPerfil = :idPerfil and u.flgAtivo is true")
					.setParameter("idPerfil", usuarioLogado.getPerfil().getPerfilAutorizacao().getIdPerfil())
					.getResultList();
				for(Usuario u : lista){
					listaUsuariosAutorizacao.add(new SelectItem(u.getIdUsuario(), u.getNome()));
				}
			}
		}
		return listaUsuariosAutorizacao;
	}

	public void setListaUsuariosAutorizacao(
			List<SelectItem> listaUsuariosAutorizacao) {
		this.listaUsuariosAutorizacao = listaUsuariosAutorizacao;
	}

	public List<SelectItem> getListaTabelasValor() {
		if (listaTabelasValor == null) {
			listaTabelasValor = new ArrayList<SelectItem>();
			listaTabelasValor.add(new SelectItem(null,"Selecione"));
		}
		return listaTabelasValor;
	}

	public void setListaTabelasValor(List<SelectItem> listaTabelasValor) {
		this.listaTabelasValor = listaTabelasValor;
	}

	public List<SelectItem> getListaUfs() {
		if (listaUfs == null) {
			listaUfs = UtilUfs.recuperaListaUfsSelectItem();
		}
		return listaUfs;
	}

	public void setListaUfs(List<SelectItem> listaUfs) {
		this.listaUfs = listaUfs;
	}

	public Integer getIdPaisCondutor() {
		return idPaisCondutor;
	}

	public void setIdPaisCondutor(Integer idPaisCondutor) {
		this.idPaisCondutor = idPaisCondutor;
	}

	public Date getDataAluguel() {
		return dataAluguel;
	}

	public void setDataAluguel(Date dataAluguel) {
		this.dataAluguel = dataAluguel;
	}

	public Automovel getAutomovelSelecionado() {
		if (automovelSelecionado == null) {
			automovelSelecionado = new Automovel();
		}
		return automovelSelecionado;
	}

	public void setAutomovelSelecionado(Automovel automovelSelecionado) {
		this.automovelSelecionado = automovelSelecionado;
	}

	public Cliente getClienteSelecionado() {
		if (clienteSelecionado == null) {
			clienteSelecionado = new Cliente();
		}
		return clienteSelecionado;
	}

	public void setClienteSelecionado(Cliente clienteSelecionado) {
		this.clienteSelecionado = clienteSelecionado;
	}

	public Cliente getClientePesquisa() {
		if (clientePesquisa == null) {
			clientePesquisa = new Cliente();
		}
		return clientePesquisa;
	}

	public void setClientePesquisa(Cliente clientePesquisa) {
		this.clientePesquisa = clientePesquisa;
	}

	public Automovel getAutomovelPesquisa() {
		if (automovelPesquisa == null) {
			automovelPesquisa = new Automovel();
		}
		return automovelPesquisa;
	}

	public void setAutomovelPesquisa(Automovel automovelPesquisa) {
		this.automovelPesquisa = automovelPesquisa;
	}

	public void mudarAba(String idAba){
		setSelectedTab(idAba);
	}
	
	public void onLoad(){
		setListaAlugueis(null);
		setListaAutomoveis(null);
		setListaClientes(null);
		setClientePesquisa(null);
		setAutomovelPesquisa(null);
		if(aluguelSelecionado != null){
			aluguelEdicao = aluguelSelecionado;
			Calendar dataSaida = Calendar.getInstance();
			Calendar dataPrevRetorno = Calendar.getInstance();
			dataSaida.setTime(aluguelEdicao.getDataSaida());
			dataPrevRetorno.setTime(getAluguelEdicao().getDataPrevistaEntrega());
			
			aluguelEdicao.setHoraSaida(dataSaida.get(Calendar.HOUR_OF_DAY));
			aluguelEdicao.setMinutoSaida(dataSaida.get(Calendar.MINUTE));
			aluguelEdicao.setHoraPrevRetorno(dataPrevRetorno.get(Calendar.HOUR_OF_DAY));
			aluguelEdicao.setMinutoPrevRetorno(dataPrevRetorno.get(Calendar.MINUTE));
			
			if(aluguelEdicao.getDataRetorno() != null){
				Calendar dataRetorno = Calendar.getInstance();
				dataRetorno.setTime(aluguelEdicao.getDataRetorno());
				aluguelEdicao.setHoraRetorno(dataRetorno.get(Calendar.HOUR_OF_DAY));
				aluguelEdicao.setMinutoRetorno(dataRetorno.get(Calendar.MINUTE));
			}
		}
	}
	
	 public boolean filterIds(Object current) {
        Aluguel currentAluguel = (Aluguel)current;
        if (filterValue == null ||
        		filterValue.length()==0) {
            return true;
        }
        if (currentAluguel.getIdAluguel().toString().startsWith(filterValue.toLowerCase())) {
            return true;
        }else {
            return false; 
        }
    }
	 
	 public boolean filterIdsFinalizados(Object current) {
        Aluguel currentAluguel = (Aluguel)current;
        if (filterValueFin == null ||
        		filterValueFin.length()==0) {
            return true;
        }
        if (currentAluguel.getIdAluguel().toString().startsWith(filterValueFin.toLowerCase())) {
            return true;
        }else {
            return false; 
        }
    }
	
	public void onLoadList(){
		setSelectedTab("tabDadosVeiculo");
		setAluguelEdicao(null);
		setCoberturaEdicao(null);
		aluguelSelecionado = null;
	}
	
	public void pesquisaClientes(){
		StringBuffer query = new StringBuffer("select c from Cliente c where c.flgAtivo is true ");
		if(getClientePesquisa().getNome() != null &&
				!getClientePesquisa().getNome().isEmpty()){
			query.append(" and UPPER(c.nome) like UPPER(:nome)");
		}
		if(getClientePesquisa().getCpf() != null &&
				!getClientePesquisa().getCpf().isEmpty()){
			query.append(" and c.cpf = :cpf");
		}
		if(getClientePesquisa().getPassaporte() != null &&
				!getClientePesquisa().getPassaporte().isEmpty()){
			query.append(" and c.passaporte = :passaporte");
		}
		if(getClientePesquisa().getNroCartaoGold() != null &&
				!getClientePesquisa().getNroCartaoGold().isEmpty()){
			query.append(" and c.nroCartaoGold = :nroCartao");
		}
		
		Query qryResult = entityManager.createQuery(query.toString());
		
		if(getClientePesquisa().getNome() != null &&
				!getClientePesquisa().getNome().isEmpty()){
			qryResult.setParameter("nome", "%"+getClientePesquisa().getNome()+"%");
		}
		if(getClientePesquisa().getCpf() != null &&
				!getClientePesquisa().getCpf().isEmpty()){
			qryResult.setParameter("cpf", getClientePesquisa().getCpf());
		}
		if(getClientePesquisa().getPassaporte() != null &&
				!getClientePesquisa().getPassaporte().isEmpty()){
			qryResult.setParameter("passaporte", getClientePesquisa().getPassaporte());
			query.append(" and c.passaporte = :passaporte");
		}
		if(getClientePesquisa().getNroCartaoGold() != null &&
				!getClientePesquisa().getNroCartaoGold().isEmpty()){
			qryResult.setParameter("nroCartao", getClientePesquisa().getNroCartaoGold());
			query.append(" and c.nroCartaoGold = :nroCartao");
		}
		
		listaClientes = qryResult.getResultList();
	}
	
	public void atualizaValores(ValorPagamento pagamento){
		if(pagamento.getQuantidade() != null){
			if(pagamento.getValorUnitario() != null){
				pagamento.setTotal(pagamento.getQuantidade() * pagamento.getValorUnitario());
			}
			if(pagamento.getDesconto() != null && pagamento.getTotal() != null){
				pagamento.setTotal(pagamento.getTotal() - pagamento.getDesconto());
			}
			atualizaTotalizadores();
		}
	}
	
	public void atualizaValoresPagamento(){
		atualizaValores(getValorKmExtra());
		atualizaValores(getValorHoraExtra());
		atualizaValores(getValorDiarias());
		atualizaValores(getValorCombustivel());
		atualizaValores(getValorTaxaLimpeza());
		atualizaValores(getValorTaxaServico());

		setValorDesconto(getValorKmExtra());
		lancarDesconto();
		setValorDesconto(getValorHoraExtra());
		lancarDesconto();
		setValorDesconto(getValorDiarias());
		lancarDesconto();
		setValorDesconto(getValorCombustivel());
		lancarDesconto();
		setValorDesconto(getValorTaxaLimpeza());
		lancarDesconto();
		setValorDesconto(getValorTaxaServico());
		lancarDesconto();
	}
	
	public void atualizaTotalizadores(){
		getValorTotal().setQuantidade(null);
		getValorTotal().setValorUnitario(null);
		getValorTotal().setDesconto(null);
		getValorTotal().setTotal(null);
		int contQtdeKmExtra = getValorKmExtra().getQuantidade() != null ? getValorKmExtra().getQuantidade() : 0; 
		int contQtdeHoraExtra = getValorHoraExtra().getQuantidade() != null ? getValorHoraExtra().getQuantidade() : 0; 
		int contQtdeDiarias = getValorDiarias().getQuantidade() != null ? getValorDiarias().getQuantidade() : 0; 
		int contQtdeTaxaServico = getValorTaxaServico().getQuantidade() != null ? getValorTaxaServico().getQuantidade() : 0; 
		int contQtdeCombustivel = getValorCombustivel().getQuantidade() != null ? getValorCombustivel().getQuantidade() : 0; 
		int contQtdeTaxaLimpeza = getValorTaxaLimpeza().getQuantidade() != null ? getValorTaxaLimpeza().getQuantidade() : 0; 
		int contQtdeProdutos = getValorProdutos().getQuantidade() != null ? getValorProdutos().getQuantidade() : 0; 
		getValorTotal().setQuantidade(contQtdeKmExtra + contQtdeHoraExtra + contQtdeDiarias + contQtdeTaxaServico + contQtdeCombustivel + contQtdeTaxaLimpeza + contQtdeProdutos);
		
		float contValorKmExtra = getValorKmExtra().getValorUnitario() != null ? getValorKmExtra().getValorUnitario() : 0; 
		float contValorHoraExtra = getValorHoraExtra().getValorUnitario() != null ? getValorHoraExtra().getValorUnitario() : 0; 
		float contValorDiarias = getValorDiarias().getValorUnitario() != null ? getValorDiarias().getValorUnitario() : 0; 
		float contValorTaxaServico = getValorTaxaServico().getValorUnitario() != null ? getValorTaxaServico().getValorUnitario() : 0; 
		float contValorCombustivel = getValorCombustivel().getValorUnitario() != null ? getValorCombustivel().getValorUnitario() : 0; 
		float contValorTaxaLimpeza = getValorTaxaLimpeza().getValorUnitario() != null ? getValorTaxaLimpeza().getValorUnitario() : 0; 
		float contValorProdutos = getValorProdutos().getValorUnitario() != null ? getValorProdutos().getValorUnitario() : 0; 
		getValorTotal().setValorUnitario(contValorKmExtra + contValorHoraExtra + contValorDiarias + contValorTaxaServico + contValorCombustivel + contValorTaxaLimpeza + contValorProdutos);
		
		float contDescontoKmExtra = getValorKmExtra().getDesconto() != null ? getValorKmExtra().getDesconto() : 0; 
		float contDescontoHoraExtra = getValorHoraExtra().getDesconto() != null ? getValorHoraExtra().getDesconto() : 0; 
		float contDescontoDiarias = getValorDiarias().getDesconto() != null ? getValorDiarias().getDesconto() : 0; 
		float contDescontoTaxaServico = getValorTaxaServico().getDesconto() != null ? getValorTaxaServico().getDesconto() : 0; 
		float contDescontoCombustivel = getValorCombustivel().getDesconto() != null ? getValorCombustivel().getDesconto() : 0; 
		float contDescontoTaxaLimpeza = getValorTaxaLimpeza().getDesconto() != null ? getValorTaxaLimpeza().getDesconto() : 0; 
//		float contDescontoProdutos = getValorProdutos().getDesconto() != null ? getValorProdutos().getDesconto() : 0; 
		getValorTotal().setDesconto(contDescontoKmExtra + contDescontoHoraExtra + contDescontoDiarias + contDescontoTaxaServico + contDescontoCombustivel + contDescontoTaxaLimpeza);
		
		float contTotalKmExtra = getValorKmExtra().getTotal() != null ? getValorKmExtra().getTotal() : 0; 
		float contTotalHoraExtra = getValorHoraExtra().getTotal() != null ? getValorHoraExtra().getTotal() : 0; 
		float contTotalDiarias = getValorDiarias().getTotal() != null ? getValorDiarias().getTotal() : 0; 
		float contTotalTaxaServico = getValorTaxaServico().getTotal() != null ? getValorTaxaServico().getTotal() : 0; 
		float contTotalCombustivel = getValorCombustivel().getTotal() != null ? getValorCombustivel().getTotal() : 0; 
		float contTotalTaxaLimpeza = getValorTaxaLimpeza().getTotal() != null ? getValorTaxaLimpeza().getTotal() : 0; 
		float contTotalProdutos = getValorProdutos().getTotal() != null ? getValorProdutos().getTotal() : 0; 
		getValorTotal().setTotal(contTotalKmExtra + contTotalHoraExtra + contTotalDiarias + contTotalTaxaServico + contTotalCombustivel + contTotalTaxaLimpeza + contTotalProdutos);
		
	}
	
	public void pesquisaAutomoveis(){
		StringBuffer query = new StringBuffer("select a from Automovel a where a.flgAtivo is true ");
		if(getAutomovelPesquisa().getMarca() != null &&
				!getAutomovelPesquisa().getMarca().isEmpty()){
			query.append("and UPPER(a.marca) = UPPER(:marca)");
		}
		if(getAutomovelPesquisa().getModelo() != null &&
				!getAutomovelPesquisa().getModelo().isEmpty()){
			query.append("and UPPER(a.modelo) = UPPER(:modelo)");
		}
		if(getAutomovelPesquisa().getPlaca() != null &&
				!getAutomovelPesquisa().getPlaca().isEmpty()){
			query.append("and UPPER(a.placa) = UPPER(:placa)");
		}
		if(getAutomovelPesquisa().getCor() != null &&
				!getAutomovelPesquisa().getCor().isEmpty()){
			query.append("and UPPER(a.cor) = UPPER(:cor)");
		}
		if(getAutomovelPesquisa().getChassi() != null &&
				!getAutomovelPesquisa().getChassi().isEmpty()){
			query.append("and UPPER(a.chassi) = UPPER(:chassi)");
		}
		if(getAutomovelPesquisa().getAnoModelo() != null){
			query.append("and UPPER(a.anoModelo) = UPPER(:anoModelo)");
		}
		if(getAutomovelPesquisa().getAnoFabricacao() != null){
			query.append("and UPPER(a.anoFabricacao) = UPPER(:anoFabricacao)");
		}
		
		Query qryResult = entityManager.createQuery(query.toString());
		
		if(getAutomovelPesquisa().getMarca() != null &&
				!getAutomovelPesquisa().getMarca().isEmpty()){
			qryResult.setParameter("marca", "%"+getAutomovelPesquisa().getMarca()+"%");
		}
		if(getAutomovelPesquisa().getModelo() != null &&
				!getAutomovelPesquisa().getModelo().isEmpty()){
			qryResult.setParameter("modelo", "%"+getAutomovelPesquisa().getModelo()+"%");
		}
		if(getAutomovelPesquisa().getPlaca() != null &&
				!getAutomovelPesquisa().getPlaca().isEmpty()){
			qryResult.setParameter("placa", getAutomovelPesquisa().getPlaca());
		}
		if(getAutomovelPesquisa().getCor() != null &&
				!getAutomovelPesquisa().getCor().isEmpty()){
			qryResult.setParameter("cor", getAutomovelPesquisa().getCor());
		}
		if(getAutomovelPesquisa().getChassi() != null &&
				!getAutomovelPesquisa().getChassi().isEmpty()){
			qryResult.setParameter("chassi", getAutomovelPesquisa().getChassi());
		}
		if(getAutomovelPesquisa().getAnoModelo() != null){
			qryResult.setParameter("anoModelo", getAutomovelPesquisa().getAnoModelo());
		}
		if(getAutomovelPesquisa().getAnoFabricacao() != null){
			qryResult.setParameter("anoFabricacao", getAutomovelPesquisa().getAnoFabricacao());
		}
		
		listaAutomoveis = qryResult.getResultList();
	}
	
	public void selecionarAutomovel(Automovel automovel){
		automovelSelecionado = automovel;
		atualizaListaTabelasValor(automovel);
	}
	
	public void atualizaListaTabelasValor(Automovel automovel){
		List<TabelaValorAutomovel> lista = entityManager
			.createQuery("select t from TabelaValorAutomovel t where t.automovel.idAutomovel = :id and t.flgAtivo is true")
			.setParameter("id", automovel.getIdAutomovel())
			.getResultList();
		setListaTabelasValor(null);
		for(TabelaValorAutomovel t : lista){
			getListaTabelasValor().add(new SelectItem(t.getIdTabelaValorAutomovel(), t.getTabelaValor().getDscTabela()));
		}
	}

	public void selecionarCliente(Cliente cliente){
		clienteSelecionado = cliente;
	}
	
	public Aluguel getAluguelEdicao() {
		if (aluguelEdicao == null) {
			aluguelEdicao = new Aluguel();
		}
		return aluguelEdicao;
	}

	public void setAluguelEdicao(Aluguel aluguelEdicao) {
		this.aluguelEdicao = aluguelEdicao;
	}

	public Cobertura getCoberturaEdicao() {
		if (coberturaEdicao == null) {
			coberturaEdicao = new Cobertura();
		}
		return coberturaEdicao;
	}

	public void setCoberturaEdicao(Cobertura coberturaEdicao) {
		this.coberturaEdicao = coberturaEdicao;
	}

	public Aluguel getAluguelSelecionado() {
		return aluguelSelecionado;
	}

	public void setAluguelSelecionado(Aluguel aluguelSelecionado) {
		this.aluguelSelecionado = aluguelSelecionado;
	}

	public HistoricoAluguel getHistoricoEdicao() {
		if (historicoEdicao == null) {
			historicoEdicao = new HistoricoAluguel();
		}
		return historicoEdicao;
	}

	public void setHistoricoEdicao(HistoricoAluguel historicoEdicao) {
		this.historicoEdicao = historicoEdicao;
	}

	public List<Aluguel> getListaAlugueis() {
		if (listaAlugueis == null) {
			listaAlugueis = entityManager.createQuery("select a from Aluguel a where a.flgAtivo is true and a.dataRetorno is null order by a.idAluguel DESC").getResultList();
			for(Aluguel a : listaAlugueis){
				Long cont = 0L;
				cont = (Long)entityManager.createQuery("select COUNT(a.idHistoricoAluguel) from HistoricoAluguel a where a.aluguel.idAluguel = :idAluguel and a.status = 'SOLICITADO' and a.flgAtivo is true")
					.setParameter("idAluguel", a.getIdAluguel())
					.getSingleResult();
				a.setShowIconeAlerta(cont > 0);
			}
		}
		return listaAlugueis;
	}

	public void setListaAlugueis(List<Aluguel> listaAlugueis) {
		this.listaAlugueis = listaAlugueis;
	}
	
	public List<Aluguel> getListaAlugueisFinalizados() {
		if (listaAlugueisFinalizados == null) {
			listaAlugueisFinalizados = entityManager.createQuery("select a from Aluguel a where a.dataRetorno is not null and a.flgAtivo is true order by a.idAluguel DESC").getResultList();
		}
		return listaAlugueisFinalizados;
	}

	public void setListaAlugueisFinalizados(List<Aluguel> listaAlugueisFinalizados) {
		this.listaAlugueisFinalizados = listaAlugueisFinalizados;
	}

	public List<HistoricoAluguel> getListaHistoricosAluguel() {
		if (listaHistoricosAluguel == null) {
			if(getAluguelEdicao() != null && getAluguelEdicao().getIdAluguel() != null){
				listaHistoricosAluguel = entityManager.createQuery("select h from HistoricoAluguel h where h.aluguel.idAluguel = :idAluguel and h.flgAtivo is true order by h.dtaHistorico DESC")
					.setParameter("idAluguel", getAluguelEdicao().getIdAluguel())
					.getResultList();
			}else{
				listaHistoricosAluguel = new ArrayList<HistoricoAluguel>();
			}
		}
		return listaHistoricosAluguel;
	}

	public void setListaHistoricosAluguel(List<HistoricoAluguel> listaHistoricosAluguel) {
		this.listaHistoricosAluguel = listaHistoricosAluguel;
	}

	public List<Cliente> getListaClientes() {
		if (listaClientes == null) {
			listaClientes = new ArrayList();
		}
		return listaClientes;
	}

	public void setListaClientes(List<Cliente> listaClientes) {
		this.listaClientes = listaClientes;
	}

	public List<Automovel> getListaAutomoveis() {
		if (listaAutomoveis == null) {
			listaAutomoveis = new ArrayList<Automovel>();
		}
		return listaAutomoveis;
	}

	public void setListaAutomoveis(List<Automovel> listaAutomoveis) {
		this.listaAutomoveis = listaAutomoveis;
	}
	
	public void calculaDataPrevistaRetorno(){
		if(getAluguelEdicao().getDataSaida() != null &&
				getAluguelEdicao().getTotalDiarias() != null){
			getAluguelEdicao().setDataPrevistaEntrega(
				UtilDate.getDataAcrescidaDias(
						getAluguelEdicao().getDataSaida(), 
						getAluguelEdicao().getTotalDiarias()));
		}
	}
	
	public String salvar(){
		if(usuarioLogado == null){
			messages.add(Severity.ERROR,"O usuário administrador não pode cadastrar/editar/finalizar aluguel.");
			return null;
		}
		if(UtilDate.data1MenorOuIgualQueData2(getAluguelEdicao().getDataPrevistaEntrega(), getAluguelEdicao().getDataSaida())){
			messages.add(Severity.ERROR,"A data de saída não pode ser maior que a data prevista para retorno.");
			return null;
		}
		if(isFinalizacao()){
			if(getAluguelEdicao().getDataRetorno() == null){
				messages.add(Severity.ERROR,"A data de retorno é de preenchimento obrigatório.");
				return null;
			}
			if(getAluguelEdicao().getKmRetorno() == null){
				messages.add(Severity.ERROR,"O km de retorno é de preenchimento obrigatório.");
				return null;
			}
			getAluguelEdicao().setUsuarioRecebimento(usuarioLogado);
			if(getAluguelEdicao().getKmSaida() > getAluguelEdicao().getKmRetorno()){
				messages.add(Severity.ERROR,"O km de saída não pode ser maior que a km de retorno.");
				return null;
			}
			if(UtilDate.data1MenorOuIgualQueData2(getAluguelEdicao().getDataRetorno(), getAluguelEdicao().getDataSaida())){
				messages.add(Severity.ERROR,"A data de saída não pode ser maior que a data de retorno.");
				return null;
			}
		}
		if(getAluguelEdicao().isFlgProprioCondutor()){
			if(getClienteSelecionado().getHabilitacao() == null ||
					getClienteSelecionado().getHabilitacao().isEmpty() ||
					getClienteSelecionado().getHabilitacaoEmissao() == null ||
					getClienteSelecionado().getHabilitacaoValidade() == null){
				messages.add(Severity.ERROR,"Os dados da habilitação do cliente não foram todos preenchidos. Cadastre-os e após retorne.");
				return null;
			}
		}
		
		Calendar dataSaida = Calendar.getInstance();
		dataSaida.setTime(getAluguelEdicao().getDataSaida());
		dataSaida.set(Calendar.HOUR_OF_DAY, getAluguelEdicao().getHoraSaida());
		dataSaida.set(Calendar.MINUTE, getAluguelEdicao().getMinutoSaida());
		getAluguelEdicao().setDataSaida(dataSaida.getTime());
		
		Calendar dataPrevRetorno = Calendar.getInstance();
		dataPrevRetorno.setTime(getAluguelEdicao().getDataPrevistaEntrega());
		dataPrevRetorno.set(Calendar.HOUR_OF_DAY, getAluguelEdicao().getHoraPrevRetorno());
		dataPrevRetorno.set(Calendar.MINUTE, getAluguelEdicao().getMinutoPrevRetorno());
		getAluguelEdicao().setDataPrevistaEntrega(dataPrevRetorno.getTime());
		
		if(getAluguelEdicao().getDataRetorno() != null){
			Calendar dataRetorno = Calendar.getInstance();
			dataRetorno.setTime(getAluguelEdicao().getDataRetorno());
			dataRetorno.set(Calendar.HOUR_OF_DAY, getAluguelEdicao().getHoraRetorno());
			dataRetorno.set(Calendar.MINUTE, getAluguelEdicao().getMinutoRetorno());
			getAluguelEdicao().setDataRetorno(dataRetorno.getTime());
		}
		
		getAluguelEdicao().setFlgAtivo(true);
		getAluguelEdicao().setAutomovel(getAutomovelSelecionado());
		if(!isFinalizacao() &&
				UtilDate.data1MenorOuIgualQueData2(getAluguelEdicao().getDataSaida(), UtilDate.getDataAtual()) &&
				UtilDate.data1MenorOuIgualQueData2(UtilDate.getDataAtual(), getAluguelEdicao().getDataPrevistaEntrega())){
			getAutomovelSelecionado().setSituacao(Automovel.SITUACAO_ALUGADO);
		}else{
			getAutomovelSelecionado().setSituacao(Automovel.SITUACAO_DISPONIVEL);
		}
		if(isFinalizacao()){
			getAluguelEdicao().setUsuarioRecebimento(usuarioLogado);
			if(getAluguelEdicao().getKmSaida() > getAluguelEdicao().getKmRetorno()){
				messages.add(Severity.ERROR,"A km de saída não pode ser maior que a km de retorno.");
				return null;
			}
		}
		entityManager.merge(getAutomovelSelecionado());
		getAluguelEdicao().setCliente(getClienteSelecionado());
		getAluguelEdicao().setFormaPagamento(entityManager.find(FormaPagamento.class, getIdFormaPagamento()));
		getAluguelEdicao().setUsuarioEntrega(usuarioLogado);
		getAluguelEdicao().setTotalAluguel(getValorTotal().getTotal());
		getAluguelEdicao().setTabelaValorAutomovel(entityManager.find(TabelaValorAutomovel.class, getIdTabelaSelecionada()));
		if(getIdPaisCondutor() != null)
			getAluguelEdicao().setPais(entityManager.find(Pais.class, getIdPaisCondutor()));
		aluguelSalvo = entityManager.merge(getAluguelEdicao());
		getValorCombustivel().setAluguel(aluguelSalvo);
		getValorCombustivel().setFlgAtivo(true);
		entityManager.merge(getValorCombustivel());
		getValorDiarias().setAluguel(aluguelSalvo);
		getValorDiarias().setFlgAtivo(true);
		entityManager.merge(getValorDiarias());
		getValorHoraExtra().setAluguel(aluguelSalvo);
		getValorHoraExtra().setFlgAtivo(true);
		entityManager.merge(getValorHoraExtra());
		getValorKmExtra().setAluguel(aluguelSalvo);
		getValorKmExtra().setFlgAtivo(true);
		entityManager.merge(getValorKmExtra());
		getValorTaxaLimpeza().setAluguel(aluguelSalvo);
		getValorTaxaLimpeza().setFlgAtivo(true);
		entityManager.merge(getValorTaxaLimpeza());
		getValorTaxaServico().setAluguel(aluguelSalvo);
		getValorTaxaServico().setFlgAtivo(true);
		entityManager.merge(getValorTaxaServico());
		getValorTotal().setAluguel(aluguelSalvo);
		getValorTotal().setFlgAtivo(true);
		entityManager.merge(getValorTotal());
		getCoberturaEdicao().setAluguel(aluguelSalvo);
		entityManager.merge(getCoberturaEdicao());
		
		for(AluguelProduto ap : getListaProdutos()){
			ap.setAluguel(aluguelSalvo);
			entityManager.merge(ap);
		}
		
		entityManager.flush();
		if(isFinalizacao()){
			messages.add(Severity.INFO,"Aluguel finalizado com sucesso.");
		}else{
			messages.add(Severity.INFO,"Aluguel salvo com sucesso.");
		}
		exibeModalConfirmacaoDesconto = true;
		return null;
	}
	
	public void limparCampos(){
		setHistoricoEdicao(null);
		aluguelSalvo = null;
		setAluguelEdicao(null);
		setValorCombustivel(null);
		setValorDiarias(null);
		setValorHoraExtra(null);
		setValorKmExtra(null);
		setValorTaxaLimpeza(null);
		setValorTaxaServico(null);
		setValorTotal(null);
		setIdFormaPagamento(null);
		setIdPaisCondutor(null);
	}
	
	public String novo(){
		setAutomovelSelecionado(null);
		setClienteSelecionado(null);
		setAluguelEdicao(null);
		setValorCombustivel(null);
		setValorDiarias(null);
		setValorHoraExtra(null);
		setValorKmExtra(null);
		setValorTaxaLimpeza(null);
		setValorTaxaServico(null);
		setValorTotal(null);
		setIdFormaPagamento(null);
		setIdPaisCondutor(null);
		setFinalizacao(false);
		return "novo";
	}
	
	public void excluir(){
		List<Aluguel> listaRemocao = new ArrayList<Aluguel>();
		for(Aluguel a : getListaAlugueis()){
			if(a.isSelecionado()){
				a.getAutomovel().setSituacao(Automovel.SITUACAO_DISPONIVEL);
				entityManager.merge(a.getAutomovel());
				a.setFlgAtivo(false);
				entityManager.merge(a);
				listaRemocao.add(a);
			}
		}
		entityManager.flush();
		getListaAlugueis().removeAll(listaRemocao);
		messages.add(Severity.INFO,"Aluguel(eis) excluído(s) com sucesso.");
	}
	
	public String editar(Aluguel aluguel, boolean finalizacao){
		aluguelSelecionado = aluguel;
		setListaHistoricosAluguel(null);
		setAutomovelSelecionado(aluguel.getAutomovel());
		atualizaListaTabelasValor(getAutomovelSelecionado());
		setClienteSelecionado(aluguel.getCliente());
		setIdTabelaSelecionada(aluguel.getTabelaValorAutomovel() != null ? aluguel.getTabelaValorAutomovel().getIdTabelaValorAutomovel() : null);
		setIdFormaPagamento(aluguel.getFormaPagamento() != null ? aluguel.getFormaPagamento().getIdFormaPagamento() : null);
		setIdPaisCondutor(aluguel.getPais() != null ? aluguel.getPais().getIdPais() : null);
		setValorCombustivel(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.COMBUSTIVEL),
				aluguel));
		setValorDiarias(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.DIARIAS),
				aluguel));
		setValorHoraExtra(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.HORA_EXTRA),
				aluguel));
		setValorKmExtra(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.KM_EXTRA),
				aluguel));
		setValorTaxaLimpeza(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TAXA_LIMPEZA),
				aluguel));
		setValorTaxaServico(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TAXA_SERVICO),
				aluguel));
		setValorTotal(recuperaValorPagamentoPorTipoEAluguel(
				dominioController.recuperaTipoValorPagamentoPorNome(TipoValorPagamento.TOTAL),
				aluguel));
		setListaProdutos(entityManager.createQuery("select a from AluguelProduto a where a.aluguel.idAluguel = :idAluguel")
				.setParameter("idAluguel", aluguel.getIdAluguel())
				.getResultList());
		atualizaTotalizadoresProduto();
		atualizaTotalizadores();
		
		try{
			setCoberturaEdicao((Cobertura)entityManager.createQuery("select c from Cobertura c where c.aluguel.idAluguel = :idAluguel")
					.setParameter("idAluguel", aluguel.getIdAluguel())
					.getSingleResult());
		}catch(NoResultException e){
			setCoberturaEdicao(new Cobertura());
		}
		
		if(finalizacao){
			setFinalizacao(finalizacao);
		}else{
			if(aluguel.getDataRetorno() != null){
				setFinalizacao(true);
			}else{
				setFinalizacao(finalizacao);
			}
		}
		return "editar";
	}
	
	public void selecionaTodos(){
		for(Aluguel a : getListaAlugueis()){
			a.setSelecionado(isSelecionadoTodos());
		}
	}
	
	public void selecionaTodosFinalizados(){
		for(Aluguel a : getListaAlugueisFinalizados()){
			a.setSelecionado(isSelecionadoTodos());
		}
	}
	
	public ValorPagamento recuperaValorPagamentoPorTipoEAluguel(TipoValorPagamento tipo, Aluguel aluguel){
		try{
			return (ValorPagamento)entityManager.createQuery("select v from ValorPagamento v where v.tipoValorPagamento.idTipoValorPagamento = :idTipoValorPagamento and v.aluguel.idAluguel = :idAluguel")
				.setParameter("idTipoValorPagamento", tipo.getIdTipoValorPagamento())
				.setParameter("idAluguel", aluguel.getIdAluguel())
				.getSingleResult();
		}catch(NoResultException e){
			return new ValorPagamento(tipo);
		}
	}
	
	public String cancelar(){
		return "voltar";
	}
	
	@SuppressWarnings("unchecked")
	public String imprimirContrato(Aluguel aluguel){
		aluguelSelecionado = aluguel;
		List<ValorPagamento> valores = entityManager.createQuery("select v from ValorPagamento v where v.aluguel.idAluguel = :idAluguel and v.flgAtivo is true and v.tipoValorPagamento.nome != :nome ")
				.setParameter("idAluguel", aluguelSelecionado.getIdAluguel())
				.setParameter("nome", TipoValorPagamento.TOTAL)
				.getResultList();
		float totalDescontos = 0F;
		for(ValorPagamento vp : valores){
			totalDescontos += vp.getDesconto() != null ? vp.getDesconto() : 0F;
		}
		aluguelSelecionado.setTotalDescontos(totalDescontos);
		return "contrato";
	}
	
	public String imprimirAutorizacao(Aluguel aluguel){
		aluguelSelecionado = aluguel;
		return "autorizacao";
	}
	
	public String imprimirTermoProtecao(Aluguel aluguel){
		aluguelSelecionado = aluguel;
		try{
			aluguelSelecionado.setCobertura((Cobertura)entityManager.createQuery("select c from Cobertura c where c.aluguel.idAluguel = :idAluguel")
					.setParameter("idAluguel", aluguel.getIdAluguel())
					.getSingleResult());
		}catch(NoResultException e){
			aluguelSelecionado.setCobertura(new Cobertura());
		}
		return "termoProtecao";
	}
	
	public String imprimirTermoProrrogacao(Aluguel aluguel){
		aluguelSelecionado = aluguel;
		try{
			aluguelSelecionado.setCobertura((Cobertura)entityManager.createQuery("select c from Cobertura c where c.aluguel.idAluguel = :idAluguel")
					.setParameter("idAluguel", aluguel.getIdAluguel())
					.getSingleResult());
		}catch(NoResultException e){
			aluguelSelecionado.setCobertura(new Cobertura());
		}
		return "prorrogacao";
	}
	
	public String imprimirRecibo(Aluguel aluguel){
		aluguelSelecionado = aluguel;
		aluguelSelecionado.setProdutosAlugados(entityManager.createQuery("select a from AluguelProduto a where a.aluguel.idAluguel = :idAluguel")
					.setParameter("idAluguel", aluguel.getIdAluguel())
					.getResultList());
		List<ValorPagamento> valores = entityManager.createQuery("select v from ValorPagamento v where v.aluguel.idAluguel = :idAluguel and v.flgAtivo is true and v.tipoValorPagamento.nome != :nome ")
			.setParameter("idAluguel", aluguel.getIdAluguel())
			.setParameter("nome", TipoValorPagamento.TOTAL)
			.getResultList();
		float totalDescontos = 0F;
		for(ValorPagamento vp : valores){
			totalDescontos += vp.getDesconto() != null ? vp.getDesconto() : 0F;
		}
		aluguelSelecionado.setTotalDescontos(totalDescontos);
		aluguelSelecionado.setPagamentoDiarias((ValorPagamento)entityManager.createQuery("select v from ValorPagamento v where v.aluguel.idAluguel = :idAluguel and v.tipoValorPagamento.nome = :nomeTipoValor")
				.setParameter("idAluguel", aluguel.getIdAluguel())
				.setParameter("nomeTipoValor", TipoValorPagamento.DIARIAS)
				.getSingleResult());
		return "recibo";
	}
	
	public String recuperaCaminhoImagem(String nomeImagem){
		FacesContext context1 = FacesContext.getCurrentInstance();
		String caminhoAplicacao = ((ServletContext) context1.getExternalContext().getContext()).getRealPath("/");
		return caminhoAplicacao+"/img/"+nomeImagem;
	}
	
	public static String valorPorExtenso(double vlr) {
		return null;
	}
	
	public String salvarSolicitacaoDesconto(){
		getHistoricoEdicao().setAluguel(aluguelSalvo);
		getHistoricoEdicao().setUsuarioSolicitante(usuarioLogado);
		getHistoricoEdicao().setUsuarioSolicitado(entityManager.find(Usuario.class, getIdUsuarioSelecionado()));
		getHistoricoEdicao().setDtaHistorico(new Date());
		getHistoricoEdicao().setFlgAtivo(true);
		getHistoricoEdicao().setUsuarioAtualizacao(usuarioLogado);
		getHistoricoEdicao().setStatus(HistoricoAluguel.STATUS_SOLICITADO);
		entityManager.merge(historicoEdicao);
		exibeModalConfirmacaoDesconto = false;
		exibeModalDesconto = false;
		limparCampos();
		messages.add(Severity.INFO,"Aluguel salvo com sucesso.");
		messages.add(Severity.INFO,"Solicitação de desconto enviada.");
		return "persisted";
	}
	
	public String exibirModalSolicitacaoDesconto(Boolean exibir){
		exibeModalConfirmacaoDesconto = false;
		exibeModalDesconto = exibir;
		if(!exibir){
			limparCampos();
			return "persisted";
		}else{
			return null;
		}
	}
	
	public void responderSolicitacaoDesconto(HistoricoAluguel historico){
		HistoricoAluguel resposta = new HistoricoAluguel();
		resposta.setAluguel(historico.getAluguel());
		resposta.setUsuarioAtualizacao(usuarioLogado);
		resposta.setUsuarioSolicitado(historico.getUsuarioSolicitado());
		resposta.setUsuarioSolicitante(historico.getUsuarioSolicitante());
		resposta.setFlgAtivo(true);
		resposta.setVlrDesconto(historico.getVlrDesconto());
		resposta.setHistoricoRespondido(historico);
		setHistoricoEdicao(resposta);
		setExibeModalRespostaDesconto(true);
	}
	
	public void cancelarResposta(){
		setHistoricoEdicao(null);
		setExibeModalRespostaDesconto(false);
	}
	
	public void salvarResposta(){
		HistoricoAluguel historicoRespondido = getHistoricoEdicao().getHistoricoRespondido();
		getHistoricoEdicao().setDtaHistorico(new Date());
		entityManager.merge(getHistoricoEdicao());
		historicoRespondido.setStatus(HistoricoAluguel.STATUS_RESPONDIDO);
		entityManager.merge(historicoRespondido);
		entityManager.flush();
		setHistoricoEdicao(null);
		setListaHistoricosAluguel(null);
		getListaHistoricosAluguel();
		messages.add(Severity.INFO,"Resposta enviada com sucesso.");
		setExibeModalRespostaDesconto(false);
	}
	
	public boolean showColunaResponder(HistoricoAluguel historico){
		if(usuarioLogado == null){
			return false;
		}
		return historico != null && historico.getUsuarioSolicitado().getIdUsuario().equals(usuarioLogado.getIdUsuario());
	}
	
	public String recuperaValorPorExtenso(Float valor){
		if(valor != null){
//			return "("+UtilString.valorPorExtenso(new Double(valor)).toUpperCase()+")";
//			UtilMoeda um = new UtilMoeda(valor);
//			return "(" + um.toString().toUpperCase() + ")";
			return "(" + NumeroPorExtenso.getDefaultInstance().converteMoeda(valor).toUpperCase() + ")";
		}else{
			return null;
		}
	}
	
	public int getAnoContrato() {
		return DataUtil.getInstance().getAno(new Date());
	}
}
